home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d13
/
pj9_3.arc
/
GLOBAL.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-10-07
|
4KB
|
236 lines
title global storage functions
include asm.inc
public global_alloc
public global_calloc
public global_free
public global_lock
public global_realloc
public global_unlock
GLOBAL_MAX equ 100 ; maximum number of storage handles
NULL_HANDLE equ 0
global_str struc
g_address dd ? ; storage address
g_lock dw ? ; storage lock count
g_size dw ? ; size of storage
global_str ends
.data?
global_count dw ? ; number of allocated handles
global_table global_str GLOBAL_MAX dup(<>)
.code
extn calloc,clear_strerror,free,malloc,realloc
;; global alloc
;
; entry CX requested size
; exit AX actual size
; BX storage handle (never zero)
; Cf if no storage
;
global_alloc proc
pushm di,es
call malloc
jc gal1 ; if not enough memory
call global_alloc_common
gal1: popm es,di
ret
global_alloc endp
;; global alloc common
;
; entry AX storage size
; ES:DI storage pointer
; exit BX storage handle
; Cf if out of handles
;
global_alloc_common proc
pushm ax,dx,cx,si,ds
mov dx,ax
mov bx,GLOBAL_MAX
mov cx,bx
cmp cx,global_count[bp]
jbe gac2 ; if out of handles
mov si,@data
mov ds,si
lea si,global_table-size global_str
gac1: add si,size global_str ; search for first free handle (SLOW!)
mov ax,wptr g_address[si]
or ax,wptr g_address[si+2]
loopnz gac1
jnz gac2 ; if unexpected error: corrupted data
mov g_lock[si],ax
mov g_size[si],dx
mov wptr g_address[si],di
mov wptr g_address[si+2],es
inc global_count[bp]
sub bx,cx ; compute non-zero handle 1..n (Cf=0)
gac2: popm ds,si,dx,cx,ax
ret
gac3: stc
jmp gac2
global_alloc_common endp
;; global calloc
;
; entry CX requested size
; exit AX actual size
; BX storage handle (never zero)
; Cf if no storage
;
global_calloc proc
pushm di,es
call calloc
jc gca1 ; if not enough memory
call global_alloc_common
gca1: popm es,di
ret
global_calloc endp
;; global free
;
; entry BX storage handle (OK if zero)
; exit BX 0
; uses AX
;
global_free proc
pushm di,es
cmpx bx,NULL_HANDLE
je gfr1 ; if NULL handle, just return
call read_global_entry
mov bx,NULL_HANDLE
jc gfr1 ; if bad handle
les di,g_address[si]
call free
mov wptr g_address[si],di
mov wptr g_address[si+2],es
gfr1: popm es,di
ret
global_free endp
;; global lock
;
; entry BX valid storage handle
; exit DS:SI storage pointer
; note DOES NOT BASH AX
;
global_lock proc
call read_global_entry
jc glk1 ; if bad handle
inc g_lock[si]
lds si,g_address[si]
glk1: ret
global_lock endp
;; global realloc
;
; entry BX storage handle
; CX new size
; exit AX actual size (if no errors)
; Cf if not enough memory
;
global_realloc proc
pushm di,si,ds,es
call read_global_entry
jc gre1 ; if bad handle
les di,g_address[si]
call realloc
jnc gre1 ; if realloc OK
mov ax,g_lock[si] ; check lock count before moving
add ax,-1
jc gre1 ; if locked, cannot move
call clear_strerror ; else clear realloc error
call malloc
jc gre1 ; if no memory
pushm ax,di,es ; copy old storage to new storage
pushm cx,si,ds
mov cx,g_size[si]
lds si,g_address[si]
rep movsb
popm ds,si,cx
les di,g_address[si] ; free old storage
call free
popm es,di,ax
mov wptr g_address[si],di ; set new storage pointer and size
mov wptr g_address[si+2],es
mov g_size[si],ax
clc
gre1: popm es,ds,si,di
ret
global_realloc endp
;; global unlock
;
; entry BX valid storage handle
; note flags do NOT change
;
global_unlock proc
pushf
pushm si,ds
call read_global_entry
jc gun1 ; if bad handle
dec g_lock[si]
gun1: popm ds,si
popf
ret
global_unlock endp
;; read global entry
;
; entry BX global handle
; exit DS:SI global table for handle
; Cf if bad handle
;
read_global_entry proc
pushm ax,dx
mov ax,@data
mov ds,ax
lea si,global_table
cmp bx,GLOBAL_MAX
ja rge1 ; if bad handle
mov ax,bx ; multiply handle by structure size
dec ax ; to select global table entry
mov dx,size global_str
mul dx
add si,ax
rge1: popm dx,ax
ret
read_global_entry endp
end